package com.zt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zt.mapper.OrdersMapper;
import com.zt.mapper.BookingsMapper;
import com.zt.pojo.Coupons;
import com.zt.pojo.Order;
import com.zt.pojo.Bookings;
import com.zt.service.CouponsService;
import com.zt.service.OrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
* @author 洪
* @description 针对表【orders(订单表)】的数据库操作Service实现
* @createDate 2025-04-10 09:58:53
*/
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Order> implements OrdersService {

    private static final Logger log = LoggerFactory.getLogger(OrdersServiceImpl.class);

    @Autowired
    private BookingsMapper bookingsMapper;

    @Autowired
    private CouponsService couponsService;

    @Override
    @Transactional
    public Order createOrder(Integer userId, Integer courseId, Integer teacherId,
                           Integer couponId, Integer bookingId, String courseName) {
        // 创建订单
        Order order = new Order();
        order.setOrderNo(generateOrderNo(bookingId));
        order.setUserId(userId);
        order.setCourseId(courseId);
        order.setTeacherId(teacherId);
        order.setCouponId(couponId);
        order.setBookingId(bookingId);

        Bookings booking;
        // 从预约信息中获取实际价格
        if (bookingId != null) {
            booking = bookingsMapper.selectById(bookingId);
            if (booking != null) {
                if (booking.getPrice() != null) {
                    order.setAmount(booking.getPrice());
                } else {
                    throw new RuntimeException("预约价格为空");
                }
                // 如果没有传入课程名称，则从预约信息中获取
                if (courseName == null || courseName.isEmpty()) {
                    order.setCourseName(booking.getKc());
                } else {
                    order.setCourseName(courseName);
                }
            } else {
                throw new RuntimeException("未找到预约信息");
            }
        } else {
            throw new RuntimeException("预约ID不能为空");
        }
        
        // 设置优惠金额（实际项目中应该根据优惠券计算）
        if (couponId != null) {
            Coupons coupons = couponsService.getById(couponId);
            if (coupons == null) {
                log.error("未找到优惠券信息, ID: {}", couponId);
                return null;
            }

            if (coupons.getType() == 1) {
                // 满减优惠券
                order.setDiscountAmount(coupons.getAmount());
            } else if (coupons.getType() == 2) {
                // 折扣优惠券：amount 表示折扣率，如 8.5 表示 85 折（即 8.5/10）
                BigDecimal originalPrice = booking.getPrice();
                BigDecimal discountRate = coupons.getAmount(); // 如 8.5

                // 校验折扣率是否合法（0 < discountRate <= 10）
                if (discountRate == null || discountRate.compareTo(BigDecimal.ZERO) <= 0 || discountRate.compareTo(new BigDecimal("10")) > 0) {
                    log.warn("优惠券折扣率不合法: couponId={}, amount={}", couponId, discountRate);
                    throw new IllegalArgumentException("优惠券折扣率必须大于0且不超过10");
                }

                // 计算折扣金额 = 原价 × (1 - 折扣率 / 10)
                BigDecimal discountAmount = originalPrice.multiply(BigDecimal.valueOf(10).subtract(discountRate))
                        .divide(BigDecimal.valueOf(10), 2, BigDecimal.ROUND_HALF_UP);

                order.setDiscountAmount(discountAmount);
                log.info("应用折扣优惠券，原价：{}，折扣率：{}折，折扣金额：{}", originalPrice, discountRate, discountAmount);

            }
        }
        
        order.setStatus(1); // 1-待付款
        order.setCreatedAt(LocalDateTime.now());
        System.out.println("order信息"+order);
        // 保存订单
        save(order);
        
        return order;
    }

    @Override
    @Transactional
    public boolean updateOrderStatus(String orderNo, Integer status) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getOrderNo, orderNo);
        
        log.info("正在更新订单状态, orderNo={}, status={}", orderNo, status);
        
        Order order = getOne(wrapper);
        if (order == null) {
            log.error("找不到订单, orderNo={}", orderNo);
            return false;
        }
        
        log.info("找到订单信息: id={}, orderNo={}, userId={}, courseId={}, status={},bookingId={}",
                order.getId(), order.getOrderNo(), order.getUserId(), order.getCourseId(), order.getStatus(),order.getBookingId());
        
        Order updateOrder = new Order();
        updateOrder.setStatus(status);
        
        // 如果是支付完成状态，设置支付时间和完成时间
        if (status == 3) {
            updateOrder.setPaidAt(LocalDateTime.now());
            updateOrder.setFinishedAt(LocalDateTime.now());
            
            // 尝试方法1：从订单号提取预约ID
            try {
                String orderNoStr = order.getOrderNo();
                log.info("订单号: {}", orderNoStr);
                
                if (orderNoStr != null && orderNoStr.length() > 16) {
                 /*   // 根据订单号生成规则提取预约ID
                    String bookingIdStr = orderNoStr.substring(12, 16);
                    log.info("从订单号提取的预约ID字符串: {}", bookingIdStr);
                    
                    Integer bookingId = Integer.parseInt(bookingIdStr);
                    log.info("解析的预约ID: {}", bookingId);*/
                    
                    // 更新预约状态为已支付(1)
                    Bookings booking = new Bookings();
                    booking.setId(order.getBookingId());
                    booking.setStatus(1);
                    booking.setUpdateTime(LocalDateTime.now());
                    
                    int rows = bookingsMapper.updateById(booking);
                    log.info("通过订单号提取法更新预约状态 bookingId={}, 影响行数={}", order.getBookingId(), rows);
                    // bookingId, rows);
                } else {
                    log.warn("订单号格式不符合预期: {}", orderNoStr);
                }
            } catch (Exception e) {
                log.error("从订单号提取预约ID失败, orderNo=" + orderNo, e);
            }
            
            // 尝试方法2：直接根据用户ID和创建时间查找最近的预约记录
            try {
                log.info("尝试根据用户ID查找最近的预约记录");
                LambdaQueryWrapper<Bookings> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Bookings::getUserId, order.getUserId())
                        .eq(Bookings::getStatus, 0)  // 状态为待支付
                        .orderByDesc(Bookings::getCreateTime)
                        .last("LIMIT 1");
                
                Bookings latestBooking = bookingsMapper.selectOne(queryWrapper);
                
                if (latestBooking != null) {
                    log.info("找到最近的预约记录: id={}, userId={}, status={}, createTime={}", 
                            latestBooking.getId(), latestBooking.getUserId(), 
                            latestBooking.getStatus(), latestBooking.getCreateTime());
                    
                    latestBooking.setStatus(1);  // 设置为已支付
                    latestBooking.setUpdateTime(LocalDateTime.now());
                    
                    int rows = bookingsMapper.updateById(latestBooking);
                    log.info("通过最近预约记录法更新预约状态 bookingId={}, 影响行数={}", latestBooking.getId(), rows);
                } else {
                    log.warn("未找到用户的最近预约记录, userId={}", order.getUserId());
                }
            } catch (Exception e) {
                log.error("查找最近预约记录失败", e); 
            }
        }
        
        boolean result = update(updateOrder, wrapper);
        log.info("订单状态更新结果: {}", result);
        return result;
    }

    @Override
    public Order getOrderByOrderNo(String orderNo) {
        return getOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNo, orderNo));
    }

    @Override
    public List<Order> getUserOrders(Integer userId) {
        return list(new LambdaQueryWrapper<Order>()
                .eq(Order::getUserId, userId)
                .orderByDesc(Order::getCreatedAt));
    }

    // 生成订单号
    private String generateOrderNo(Integer appointmentId) {
        String timestamp = LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
        String randomNum = String.format("%04d", (int)(Math.random() * 10000));
        String bookingId = appointmentId != null ? appointmentId.toString() : "0000";
        return String.format("%s%s%s", timestamp, bookingId, randomNum);
    }
}
